/** @file util.h
    @brief Header file for some util structures ...

    @author Juan Pablo Carbajal
    
    @date 21. July, 2008
    
*/
#ifndef _SAUTIL_H_
#define _SAUTIL_H_

#include "chipmunk/chipmunk.h"

struct DataforForce;
typedef void (*SingForceFunc)(DataforForce* data);

struct DataforBehavior;
typedef void (*BehaviorFunc)(DataforBehavior* data);

/**	@struct Vector
	@brief Three dimensional labeled vector.

	Local definition of a vector used to load the components of the XML vectors.
	Is also used for ease the translation into the different simulators.
*/
typedef struct Vector {
	const char* id;
	double x;
	double y;
	double z;
} vect;

/**	@struct acParam
	@brief Structure for storing the paramters of acBehavior and acKinematic
*/
typedef struct paramAcParam {

	/** @brief Name of the parameter*/
    const char* name;
	/** @brief Value of the parameter */
    const char* value;

} acParam;

/**	@struct acSingularity
	@brief Stores information about singularities in the actors

	  Parameters about the singularities in tha actors (point mass, charges,
														etc..) are stored here.

*/
typedef struct paramActSingularity {

	/** @brief The type of singularity */
    char* type;
	/** @brief Scalar value of singularity */
    double value;
	/** @brief Position in the actor */
    vect position;
	/** @brief Angle respect to the axis of the actor in radians*/
	double angle;

} acSingularity;

/**	@struct acBehavior
	@brief Stores information about singularities the behavior of the actors

	  Parameters describing the behavior of each actor (or describing how to
	  obtain the behavior) are stored here.
*/
typedef struct paramActSetsBehavior {

	/** @brief Source of the behaviors for the actors*/
	const char* source;
	/** @brief Number of parameters required*/
    int Nparam;
	/** @brief Vector of parameters*/
    acParam* params;

} acBehavior;

/**	@struct acKinematic
	@brief Stores Kinematic information of the actors

	  Parameters describing the kinematic of each actor (or describing how to
	  obtain this kinematic) are stored here.
*/
typedef struct paramActKinematic {

	/** @brief Source of the kinematics for the actors*/
	const char* source;
	/** @brief Number of parameters required*/
    int Nparam;
	/** @brief Vector of parameters*/
    acParam* params;

} acKinematic;

/**	@struct acSet
	@brief Stores information about a set of the actors

	  Parameters describing a set of actors are stored here.

	@warning Kinematics and behaviors are currently both stored in each actor
		  set.
*/
typedef struct paramActSet {

	/** @brief Name of the set */
	char* Name;
	/** @brief Number of actors in the set*/
    int Nactors;
	/** @brief Number of vertices of each actors*/
	int Nvertices;
	/** @brief Number of singularities in each actors*/
	int Nsingularities;

	/** @brief Position in the actor fo the center of mass*/
	vect centerOfMass;
	/** @brief Array of verices*/
	vect* vertices;

	/** @brief Type of primitive (circle, cube, etc...)*/
    char* shapeType;
	/** @brief characteristic size of the primitive (radius, arista, etc...)*/
	double size;
	/** @brief Mass of the actor*/
	double mass;

	/** @brief Elasticity of the actor's surface*/
	double elasticity;
	/** @brief Friction of the actor's surface*/
	double friction;
	/** @brief Speed of the actor's surface*/
    double surfaceSpeed;

	/** @brief Array of singularities*/
    acSingularity* singularities;
	/** @brief Kinematic data*/
    acKinematic kinematic;
	/** @brief Behavior data*/
	acBehavior behavior;

} acSet;

/**	@struct paramActor
	@brief Stores the sets of actores defined for the simulation
*/
typedef struct paramActor {

	/** @brief Number of sets defined*/
	int Nsets;
	/** @brief Array of sets*/
	acSet* sets;

} paramActor;





typedef struct ActorSingularity{
	/** @brief Number of singularities*/ 
	int Nsing; 
	/** @brief Array of singularities*/ 
	acSingularity* sing;
	/** @brief Global position of the singularities*/ 
	cpVect* Gpos;
	/** @brief Angle of the singularities measured from x*/ 
	cpFloat* Gangle;
	/**@brief Force function*/
	SingForceFunc* force_func;
	/**@brief Force function*/
	SingForceFunc* torque_func;
}Sing;

typedef struct ActorBehavior{
	/** @brief Number of behavior functions*/
	int Nbehav;
	/** @brief Data parsed from file*/
	acBehavior data;
    /** @brief Array of behavior functions*/
    BehaviorFunc* behav_func;
}Behav;

typedef struct ActorData{
	char* setname;
	Sing* singularity;
	Behav* behavior;
}ActorData;

typedef struct DataforForce{
	//Everything in global coordinates
	cpVect p0;
	cpVect p;
	cpVect relp;
	cpFloat r[3];
	cpFloat ang0;
	cpFloat ang;
	cpVect F;
}ForceData;

typedef struct DataforBehavior{
	cpBody* body;
	cpFloat param[2];
}BehavData;

#endif
